package view;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.*;

import view.graph.GraphFrame;

import listeners.BlockMouseListener;
import listeners.DraggedMouseMotionListener;
import listeners.ExitListener;
import listeners.LineMouseListener;
import listeners.OpenListener;
import listeners.SaveListener;
import listeners.SelectMouseListener;
import model.DataModel;

public class EditorFrame {
	private JFrame frame;
	private PictureModel pictureModel;
	public static DataModel datamodel;
	private JTextPane textPane;
	private DrawPanel paint;
	private BlockMouseListener blockListener;
	private LineMouseListener lineListener;
	private SelectMouseListener selectListener;
	private DraggedMouseMotionListener dragMoutionListener;
	private boolean isBlockListener=true;
	private ArrayList<JButton> buttons = new ArrayList<JButton>();
	private ArrayList<JButton> toolbarButtons = new ArrayList<JButton>();
	
	public EditorFrame() {
		frame = new JFrame("FlowchartEditor");
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		Image image = toolkit.getImage("icon/editor.png ");
		frame.setIconImage(image);
		textPane = new JTextPane();
		paint = new DrawPanel();
		paint.setBackground(Color.WHITE);
		paint.setPreferredSize(new Dimension(800,800));
		pictureModel = new PictureModel(paint);
		blockListener = new BlockMouseListener(paint,buttons,pictureModel,textPane);
		lineListener = new LineMouseListener(paint,buttons,toolbarButtons,pictureModel,textPane);
		selectListener = new SelectMouseListener(pictureModel,paint);
		dragMoutionListener = new DraggedMouseMotionListener(selectListener,paint,pictureModel,textPane);
		paint.addMouseListener(blockListener);
		
	}
	/**
	 * launch frame with components
	 */
	public void launchFrame() {
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setPreferredSize(new Dimension(1000, 600));
		frame.pack();
		// menu
		JMenuBar menuBar = new JMenuBar();
		JMenu menu = new JMenu("File");
		JMenuItem itemOpen = new JMenuItem("Open");
		itemOpen.addActionListener(new OpenListener(frame,pictureModel,paint,textPane));
		menu.add(itemOpen);
		menu.addSeparator();

		JMenuItem itemSave = new JMenuItem("Save");
		itemSave.addActionListener(new SaveListener(frame,pictureModel,textPane));
		menu.add(itemSave);
		menu.addSeparator();

//		JMenuItem itemSaveAs = new JMenuItem("Save as");
//		menu.add(itemSaveAs);
//		menu.addSeparator();

		JMenuItem itemExit = new JMenuItem("Exit");
		itemExit.addActionListener(new ExitListener());
		menu.add(itemExit);
		menuBar.add(menu);

		JMenu menuHelp = new JMenu("Help");
		menuBar.add(menuHelp);

		frame.setJMenuBar(menuBar);
		// buttons
		JButton openButton = new JButton(new ImageIcon("icon/open.png"));
		openButton.setBorder(null);
		openButton.setSize(32, 32);
		openButton.setToolTipText("Open new File");
		openButton.addActionListener(new OpenListener(frame,pictureModel,paint,textPane));

		JButton saveButton = new JButton(new ImageIcon("icon/save.png"));
		saveButton.setBorder(null);
		saveButton.setSize(32, 32);
		saveButton.setToolTipText("Save");
		saveButton.addActionListener(new SaveListener(frame,pictureModel,textPane));

//		JButton saveasButton = new JButton(new ImageIcon("icon/save2.jpg"));
//		saveasButton.setBorder(null);
//		saveasButton.setSize(32, 32);
//		saveasButton.setToolTipText("Save as");
		
		JButton selectButton = new JButton(new ImageIcon("icon/cursor.png"));
		selectButton.setBorder(null);
		selectButton.setSize(32, 32);
		selectButton.setToolTipText("Select mode");
		
		JButton drawButton = new JButton(new ImageIcon("icon/pencil.png"));
		drawButton.setBorder(null);
		drawButton.setSize(32, 32);
		drawButton.setToolTipText("Draw mode");
		
		JButton cleanButton = new JButton(new ImageIcon("icon/clean.png"));
		cleanButton.setBorder(null);
		cleanButton.setSize(32, 32);
		cleanButton.setToolTipText("Clean all");
		
		JButton ruleButton = new JButton(new ImageIcon("icon/rule.png"));
		ruleButton.setBorder(null);
		ruleButton.setSize(32, 32);
		ruleButton.setToolTipText("Check diagram");
		
		JButton graphButton = new JButton(new ImageIcon("icon/model.png"));
		graphButton.setBorder(null);
		graphButton.setSize(32, 32);
		graphButton.setToolTipText("Create graph");

		JButton exitButton = new JButton(new ImageIcon("icon/exit.png"));
		exitButton.addActionListener(new ExitListener());
		exitButton.setBorder(null);
		exitButton.setSize(32, 32);
		exitButton.setToolTipText("Exit");
		
		// toolbar
		JToolBar toolbar = new JToolBar();

		frame.add(toolbar, BorderLayout.NORTH);
		toolbar.add(openButton);
		toolbar.addSeparator();
		toolbar.add(saveButton);
		toolbar.addSeparator();
		//toolbar.add(saveasButton);
		//toolbar.addSeparator();
		toolbar.add(selectButton);
		toolbar.addSeparator();
		toolbar.add(drawButton);
		toolbar.addSeparator();
		toolbar.add(cleanButton);
		toolbar.addSeparator();
		toolbar.add(ruleButton);
		toolbar.addSeparator();
		toolbar.add(graphButton);
		toolbar.addSeparator();
		toolbar.add(exitButton);
		
		// elements pallet 
		JPanel pallet = new JPanel();
		pallet.setLayout(new GridLayout(5,1));
		final JButton startButton = new JButton("Start");	
		pallet.add(startButton);
		final JButton endButton = new JButton("End");
		pallet.add(endButton);
		final JButton yButton = new JButton("Y");
		pallet.add(yButton);
		final JButton xButton = new JButton("X");
		pallet.add(xButton);
		final JButton lineButton = new JButton("Line");
		pallet.add(lineButton);
		frame.add(pallet,BorderLayout.WEST);
		buttons.add(startButton);
		buttons.add(endButton);
		buttons.add(yButton);
		buttons.add(xButton);
		buttons.add(lineButton);
		toolbarButtons.add(selectButton);
		toolbarButtons.add(drawButton);
		toolbarButtons.add(cleanButton);
		toolbarButtons.add(ruleButton);
		
		//listeners
		startButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				chooseBlockListener();			
				setDisenable(endButton,yButton,xButton,lineButton);
				blockListener.setCurrentBlock(new StartBlock());
			}
		});
		endButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				chooseBlockListener();
				setDisenable(startButton,yButton,xButton,lineButton);
				blockListener.setCurrentBlock(new EndBlock());
			}
		});
		yButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				chooseBlockListener();
				setDisenable(startButton,endButton,xButton,lineButton);
				blockListener.setCurrentBlock(new OperationBlock());				
			}
		});
		
		xButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				chooseBlockListener();
				setDisenable(startButton,endButton,yButton,lineButton);
				blockListener.setCurrentBlock(new IfBlock());
			}
		});
		lineButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				textPane.setText("");
				paint.removeMouseListener(blockListener);
				pictureModel.drawControlPoints();
				isBlockListener = false;
				lineListener = new LineMouseListener(paint, buttons, toolbarButtons, pictureModel,textPane);
				paint.addMouseListener(lineListener);
			}
		});
		
		selectButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				setDisenable(startButton,endButton,yButton,xButton,lineButton);
				paint.setCursor(Cursor.getDefaultCursor());
				removeAllLidteners();
				paint.addMouseListener(selectListener);
				paint.addMouseMotionListener(dragMoutionListener);
				paint.clear();
				pictureModel.draw();
			}
		});
		
		drawButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				setEnabled(startButton,endButton,yButton,xButton,lineButton);
				removeAllLidteners();
				paint.addMouseListener(blockListener);				
			}
		});
		
		cleanButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				pictureModel.setBlocks(new ArrayList<Block>());
				pictureModel.setLines(new ArrayList<Line>());
				lineListener.setPath(null);
				paint.createEmptyImage();
				paint.repaint();
			}
		});
		ruleButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if(!pictureModel.hasStartEnd()){
					textPane.setText("Need Start and End blocks!!!");
					return;
				}
				datamodel = new DataModel(pictureModel);
				datamodel.printWrapper(datamodel.getWrapper());
				pictureModel.drawZ();
				datamodel.printCycle();
				ArrayList<ArrayList<Integer>> infinity = datamodel.checkInfiniteCycle();
				if(infinity != null){
					datamodel.printInfinity(infinity);
					pictureModel.drawInfinityCycleAsRed(infinity);
				}
			}
		});
		graphButton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				GraphFrame graphFrame = new GraphFrame(frame);
				graphFrame.launchFrame();
				
			}
		});
		
		// paint area
		JScrollPane scroll1 = new JScrollPane(paint);
		frame.add(scroll1, BorderLayout.CENTER);
		// text Pane
		textPane.setSelectedTextColor(Color.BLACK);
		textPane.setFont(new Font("DialogInput", Font.PLAIN, 18));
		textPane.setForeground(Color.RED);
		textPane.setBorder(BorderFactory.createTitledBorder("Console"));
		
		JScrollPane scroll2 = new JScrollPane(textPane);
		frame.add(scroll2, BorderLayout.SOUTH);
		frame.setVisible(true);
	}
	/**
	 * choose block Listener in draw mode
	 */
	private void chooseBlockListener(){
		textPane.setText("");
		if(!isBlockListener){
			paint.removeMouseListener(lineListener);
			paint.clear();
			pictureModel.draw();
			paint.addMouseListener(blockListener);
			paint.setCursor(Cursor.getDefaultCursor());
		}
		
	}
	/**
	 * disable buttons
	 *  @param buttons
	 */
	private void setDisenable(JButton ...buttons){
		for(JButton b:buttons){
			b.setEnabled(false);
		}
	}
	/**
	 * enabled buttons
	 * @param buttons 
	 */
	private void setEnabled(JButton ...buttons){
		for(JButton b:buttons){
			b.setEnabled(true);
		}
	}
	private void removeAllLidteners(){
		paint.removeMouseListener(blockListener);
		paint.removeMouseListener(lineListener);
		paint.removeMouseListener(selectListener);
		paint.removeMouseMotionListener(dragMoutionListener);
	}

	public static void main(String[] args) {
		EditorFrame editor = new EditorFrame();
		editor.launchFrame();
	}
}

